package com.easylinkin.linkappapi.redis;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;

//import static com.easylinkin.linkappapi.listener.AirMonitorListener.WS_AIRMONITOR_LISTEN;
//import static com.easylinkin.linkappapi.listener.AlarmListener.WS_ALARM_LISTEN;
//import static com.easylinkin.linkappapi.listener.DeviceAlarmListener.WS_DEVICEALARM_LISTEN;
//import static com.easylinkin.linkappapi.listener.DeviceAttributeStatusListener.WS_DEVICEATTRIBUTESTATUS_LISTEN;
//import static com.easylinkin.linkappapi.listener.DeviceMonitorListener.WS_DEVICEMONITOR_LISTEN;

@Configuration
public class RedisConfig {

//    @Autowired
//    @Qualifier(com.easylinkin.linkappapi.listener.AEPRedisListener.SERVICE_NAME)
//    private MessageListener messageListener;

    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

//    @Bean
//    MessageListenerAdapter listenerAdapter() {
//        return new MessageListenerAdapter(messageListener);
//    }
    
    @Bean
//    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
    	RedisMessageListenerContainer container = new RedisMessageListenerContainer();

        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(50);
        threadPoolTaskExecutor.setMaxPoolSize(100);
        threadPoolTaskExecutor.setQueueCapacity(100);
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        threadPoolTaskExecutor.afterPropertiesSet();
        container.setTaskExecutor(threadPoolTaskExecutor);
    	container.setConnectionFactory(connectionFactory);

//        container.addMessageListener(listenerAdapter, new PatternTopic("__keyevent@0__:expired"));
//        container.addMessageListener(listenerAdapter, new PatternTopic(WS_ALARM_LISTEN));
//        container.addMessageListener(listenerAdapter, new PatternTopic(WS_AIRMONITOR_LISTEN));
//        container.addMessageListener(listenerAdapter, new PatternTopic(WS_DEVICEALARM_LISTEN));
//        container.addMessageListener(listenerAdapter, new PatternTopic(WS_DEVICEMONITOR_LISTEN));
//        container.addMessageListener(listenerAdapter, new PatternTopic(WS_DEVICEATTRIBUTESTATUS_LISTEN));

    	return container;
    }


    @Bean
    public KeyExpirationEventMessageListener keyExpirationEventMessageListener(RedisMessageListenerContainer container) {
    	return new KeyExpirationEventMessageListener(container);
    }

}
